<?php

class PaymentUtil
{

    public function applySalesOrderPaymentToInvoice($salesOrderNumber, $paymentId, $invoiceNumber)
    {
        $salesOrder = Invoice::model()->findByPk($salesOrderNumber);
        $invoice = Invoice::model()->findByPk($invoiceNumber);
        $salesOrderRecLedApply = RecLedApply::model()->find('id=:id and type=:type', array('id' => $paymentId, 'type' => RecLed::TYPE_DP));

        if ($salesOrder != null && $invoice != null)
        {
            if ($salesOrderRecLedApply != null)
            {
                $soRecLed = RecLed::model()->find('entryid=:ledgerentryid', array(
                    'ledgerentryid' => $salesOrderRecLedApply->ledgerentryid
                        ));
                if ($soRecLed)
                {
                    $totalAmount = $salesOrderRecLedApply->paid;

                    $appliedRecLedApply = new RecLedApply();
                    $appliedRecLedApply->paid = $salesOrderRecLedApply->paid;
                    $appliedRecLedApply->ledgerentryid = $salesOrderRecLedApply->ledgerentryid;
                    $appliedRecLedApply->applieddate = $salesOrderRecLedApply->applieddate;
                    $appliedRecLedApply->jobid = $salesOrderRecLedApply->jobid;
                    $appliedRecLedApply->type = RecLed::TYPE_NORMAL;
                    $appliedRecLedApply->number = $invoiceNumber;
                    $appliedRecLedApply->custno = $salesOrderRecLedApply->custno;
                    $appliedRecLedApply->locno = $salesOrderRecLedApply->locno;
                    $appliedRecLedApply->memo = $salesOrderRecLedApply->memo;

                    $rec = Rec::model()->find('invoice=:invoice', array('invoice' => $invoiceNumber));
                    if ($rec != null)
                    {
                        $appliedAmount = $salesOrderRecLedApply->paid;
                        $remainAmount = 0;
                        if ($appliedAmount + $rec->paid > $rec->invamt)
                        {
                            $appliedAmount = $rec->invamt - $rec->paid;
                            $remainAmount = $totalAmount - $appliedAmount;
                        }
                        $rec->paid+=$appliedAmount;
                        if ($rec->paid == $rec->invamt)
                        {
                            $rec->paidoff = date('Y-m-d H:i:s');
                        }
                        if ($remainAmount > 0)
                        {
                            $creditRecLed = new RecLed; //prepayment recled

                            $creditRecLed->locno = $invoice->locno;
                            $creditRecLed->custno = $invoice->custno;
                            $creditRecLed->ckdate = $salesOrderRecLedApply->applieddate;
                            $creditRecLed->paymethod = 'Check';
                            $creditRecLed->ckno = null;
                            $creditRecLed->period = date('Ym');
                            $creditRecLed->source = 'R';
                            $creditRecLed->debit = '1099';
                            $creditRecLed->credit = '1110';
                            $creditRecLed->entryid = NULL;
                            $creditRecLed->type = RecLed::TYPE_CREDIT;
                            $creditRecLed->applied = 0;
                            $creditRecLed->amount = $remainAmount;
                            //$precled->appliedfromid = $recleg->entryid;
                            $creditRecLed->save();
                        }
                    }
                    else
                    {
                        return false;
                    }
                    $salesOrderRecLedApply->type = RecLed::TYPE_APPLIED;
                    $soRecLed->applied +=$appliedAmount;
                    
                    if ($appliedRecLedApply->save() && $salesOrderRecLedApply->save() && $rec->save() && $soRecLed->save())
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public function applyDeposit($number)
    {
        
    }

    public function savePayment($paymentList, $paymentAmount, $paymentMethod, $checkNo, $memo, $date=null)
    {
        if ($date == null)
        {
            $date = date('Y-m-d');
        }
        $invoiceList = array();
        $saleOrderList = array();
        $totalApplied = 0;
        $unapplied = 0;
        $normalPayment = 0;
        $depositPayment = 0;
        $custno = $locno = null;
        foreach ($paymentList as $payment)
        {
            $invoiceNumber = $payment['invoice'];
            $invoice = Invoice::model()->findByPk($invoiceNumber);
            if ($invoice == null)
            {
                //$this->showAjaxMessage('Invoice ' . $invoiceNumber . ' can not be found', false);
                throw new CException('Invoice ' . $invoiceNumber . ' can not be found', 500);
                return false;
            }
            else
            {
                if ($custno == null && $locno == null)
                {
                    $custno = $invoice->custno;
                    $locno = $invoice->locno;
                }
                if ($invoice->invoicetype != Invoice::TYPE_INVOICE && $invoice->invoicetype != Invoice::TYPE_SALES_ORDERS)
                {
                    //$this->showAjaxMessage('Only Invoice and Sale Order are allowed to process');
                    throw new CException('Only Invoice and Sale Order are allowed to process', 500);
                }
                else
                {
                    $appliedamount = null;
                    if ($invoice->invoicetype == Invoice::TYPE_INVOICE)
                    {
                        $rec = Rec::model()->find('invoice=:invoice', array(
                            'invoice' => $payment['invoice']
                                ));
                        $total = null;
                        $paid = null;
                        if ($rec == NULL)
                        {
                            throw new CException('Rec for invoice ' . $invoice->invoice . ' can not be found', 500);
                            return false;
                        }
                        else
                        {
                            $total = $rec->invamt;
                            $paid = $rec->paid;
                        }
                        $appliedamount = $payment['appliedamount'];
                        $newapplied = 0;
                        if ($total < $paid + $appliedamount)
                        {
                            $appliedamount = $total - $paid;
                        }
                    }
                    else
                    {
                        $appliedamount = $payment['appliedamount'];
                    }
                    $payment['appliedamount'] = $appliedamount;
                    if ($invoice->invoicetype == Invoice::TYPE_INVOICE)
                    {
                        $invoiceList[] = $payment;
                        $normalPayment+=$payment['appliedamount'];
                    }
                    else if ($invoice->invoicetype == Invoice::TYPE_SALES_ORDERS)
                    {
                        $saleOrderList[] = $payment;
                        $depositPayment+=$payment['appliedamount'];
                    }
                    $totalApplied+=$appliedamount;
                }
            }
        }
        if (count($invoiceList) > 0)
        {
            $r = $this->saveInvoicePayment($custno, $locno, $invoiceList, $normalPayment, $paymentMethod, $checkNo, $memo, $date);
            if (!$r)
            {
                throw new CException('Can not save invoice payment', 500);
            }
        }
        if (count($saleOrderList) > 0)
        {
            $r = $this->saveSalesOrderPayment($custno, $locno, $saleOrderList, $depositPayment, $paymentMethod, $checkNo, $memo, $date);
            if (!$r)
            {
                throw new CException('Can not save sales order payment', 500);
            }
        }
        $unapplied = $paymentAmount - $totalApplied;
        if ($unapplied > 0)
        {
            $creditRecLed = new RecLed; //prepayment recled

            $creditRecLed->locno = $locno;
            $creditRecLed->custno = $custno;
            $creditRecLed->ckdate = $date;
            $creditRecLed->paymethod = $paymentMethod;
            $creditRecLed->ckno = $checkNo;
            $creditRecLed->period = date('Ym');
            $creditRecLed->source = 'R';
            $creditRecLed->debit = '1099';
            $creditRecLed->credit = '1110';
            $creditRecLed->entryid = NULL;
            $creditRecLed->type = RecLed::TYPE_CREDIT;
            $creditRecLed->applied = 0;
            $creditRecLed->amount = $unapplied;
            //$precled->appliedfromid = $recleg->entryid;
            $creditRecLed->save();
        }
        //$this->showAjaxMessage('Save successful', true);
        return true;
    }

    public function saveInvoicePayment($custno, $locno, $invoicePayment, $invoiceAmount, $paymentMethod, $checkNo, $memo, $date)
    {


        $recleg = new RecLed;
        //save only 1 records for all
        $recleg->custno = $custno;
        $recleg->locno = $locno;
        $recleg->entrydate = $date;
        $recleg->paymethod = $paymentMethod;
        $recleg->ckno = $checkNo;
        $recleg->amount = $invoiceAmount;
        $recleg->applied = $invoiceAmount;
        $recleg->period = date('Ym');
        $recleg->memo = $memo;
        $recleg->source = 'R';
        $recleg->debit = '1099';
        $recleg->credit = '1110';
        $recleg->type = RecLed::TYPE_NORMAL;
        //$recleg->remaincredit = $totalRemaining;
        //$recleg->applied    = $totalApplied;
        if (!$recleg->save())
        {
            //$this->showAjaxMessage('Error while saving data');
            throw new CException('Error while saving RecLed', 500);
        }


        //save to the ledger
        $log1 = new Xlogrec;

        $log1->transdate = $date;
        $log1->entryid = $recleg->entryid;
        $log1->invoice = $recleg->invoice;
        $log1->amount = $invoiceAmount;
        $log1->memo = 'RecRecordPayment: Added line to receivables journal entry';
        $log1->counter = 0;
        $log1->custno = $recleg->custno;

        $log2 = new Xlogrec;

        $log2->transdate = $date;
        $log2->entryid = $recleg->entryid;
        $log2->invoice = $recleg->invoice;
        $log2->amount = -$invoiceAmount;
        $log2->memo = 'RecRecordPayment: Recorded payment record in RecLed';
        $log2->counter = 1;
        $log2->custno = $recleg->custno;
        if (!($log1->save() && $log2->save()))
        {
            //$this->showAjaxMessage('Error saving log', false);
            throw new CException('Error saving log', 500);
        }

        foreach ($invoicePayment as $i => $item)
        {

            //$transaction = Yii::app()->db->beginTransaction();
            $invoice = Invoice::model()->findByPk($item['invoice']);
            if ($invoice->invoicetype == Invoice::TYPE_INVOICE)
            {

                $appliedamount = 0;
                $appliedamount = $item['appliedamount'];
                /* @var $invoice Invoice */
                $rec = Rec::model()->find('invoice=:invoice', array(
                    'invoice' => $item['invoice']
                        ));
                /* @var $rec Rec */
                if ($rec == NULL)
                {
                    //$this->showAjaxMessage('Error while saving data');
                    throw new CException('Error while saving data', 500);
                }
                $rec->invdate = $invoice->invoicedate;
                $rec->period = date('Ym');
                $rec->transid = createRandomUUID();
                $rec->jobnumber = $invoice->jobnumber;
                $rec->paid += $appliedamount;
                $rec->lastpaid = date('Y-m-d H:i:s');                
                if ($rec->paid >= $rec->invamt)
                    $rec->paidoff = date('Y-m-d H:i:s');
                /*
                 * 1. Record payment into tbl_rec_led
                  2. record what it was applied to in rec_leg_applied
                  3. save paid amount to invoice in tbl_rec
                  4. add the amount applied to tbl_rec_led.applied
                 */
                //check for type, 
                if ($rec->save())
                {
                    //save a record to rec led applied
                    $recledApply = new RecLedApply;
                    $recledApply->custno = $custno;
                    $recledApply->locno = $locno;
                    $recledApply->ledgerentryid = $recleg->entryid;
                    $recledApply->paid = $appliedamount;
                    //$recledApply->jobid         = $_POST['jobid'];
                    $recledApply->memo = $memo;
                    $recledApply->applieddate = $date;
                    $recledApply->type = RecLed::TYPE_NORMAL;
                    $recledApply->number = $invoice->invoice;
                    $recledApply->save();
                    if ($recledApply->save() == false)
                    {
                        //$this->showAjaxMessage('Error while saving data');
                        throw new CException('Error while saving RecLedApply', 500);
                    }else{
                        //mark dispatch as complete
                        if($invoice->checkPaid()){
                            $invoice->markDispatchComplete();
                        }
                    }
                }
                else
                {
                    //$this->showAjaxMessage('Error while saving data');
                    throw new CException('Error while saving Rec', 500);
                }
            }
        }
        return true;
    }

    public function saveSalesOrderPayment($custno, $locno, $payments, $paymentAmount, $paymentMethod, $checkNo, $memo, $date)
    {

        $recleg = new RecLed;
        //save only 1 records for all
        $recleg->custno = $custno;
        $recleg->locno = $locno;
        $recleg->entrydate = $date;
        $recleg->paymethod = $paymentMethod;
        $recleg->ckno = $checkNo;
        $recleg->amount = $paymentAmount;
        $recleg->period = date('Ym');
        $recleg->memo = $memo;
        $recleg->source = 'R';
        $recleg->debit = '1099';
        $recleg->credit = '1110';
        $recleg->type = RecLed::TYPE_DP;
        //$recleg->remaincredit = $totalRemaining;
        //$recleg->applied = $totalApplied;
        if (!$recleg->save())
        {
            //$this->showAjaxMessage('Error while saving data');
            throw new CException('Error while saving RecLed');
            return false;
        }
        foreach ($payments as $i => $item)
        {

            //$transaction = Yii::app()->db->beginTransaction();
            $invoice = Invoice::model()->findByPk($item['invoice']);
            $appliedamount = 0;
            $appliedamount = $item['appliedamount'];
            /* @var $invoice Invoice */
            /*
             * 1. Record payment into tbl_rec_led
              2. record what it was applied to in rec_leg_applied
              3. save paid amount to invoice in tbl_rec
              4. add the amount applied to tbl_rec_led.applied
             */

            //check for type, 
            //save a record to rec led applied
            $recledApply = new RecLedApply;
            $recledApply->custno = $custno;
            $recledApply->locno = $locno;
            $recledApply->ledgerentryid = $recleg->entryid;
            $recledApply->paid = $appliedamount;
            //$recledApply->jobid = $_POST['jobid'];
            $recledApply->memo = $item['memo'];
            $recledApply->applieddate = $date;
            $recledApply->type = RecLed::TYPE_DP;
            $recledApply->number = $invoice->invoice;
            $recledApply->save();
            if ($recledApply->save() == false)
            {
                //$this->showAjaxMessage('Error while saving data');
                throw new CException('Error when saving RecLedApply');
            }
        }
        return true;
    }

}